import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import '../serve/file_serve.dart';
import 'OCR.dart';
import 'tina_dart/BaseAPI.dart';
import 'package:uuid/uuid.dart';
import 'package:intl/intl.dart';

/// 屏幕截图服务，用于处理截图的OCR识别和文档生成
class ScreenShotServe {
  final FileServe _fileServe;
  late OCR _ocr;
  late BaseAPI _llm;
  bool _isInitialized = false;
  
  ScreenShotServe(this._fileServe);
  
  /// 初始化截图服务
  Future<void> initialize(BaseAPI llm) async {
    if (_isInitialized) return;
    
    _llm = llm;
    
    try {
      print('ScreenShotServe: 开始初始化OCR服务...');
      
      // 从配置文件中获取OCR设置
      final ocrConfig = await _fileServe.getConfig('vivo_ocr');
      print('ScreenShotServe: 获取到OCR配置: $ocrConfig');
      
      if (ocrConfig.isNotEmpty) {
        print('ScreenShotServe: 创建OCR实例，app_id=${ocrConfig['app_id']}');
        _ocr = OCR(
          appId: ocrConfig['app_id'] ?? '',
          secretKey: ocrConfig['secret_key'] ?? '',
          apiUrl: ocrConfig['api_url'] ?? '',
          llm: _llm,
        );
        
        _isInitialized = true;
        print('ScreenShotServe: OCR服务初始化成功');
      } else {
        print('ScreenShotServe: 无法获取OCR配置，配置为空');
        throw Exception('无法初始化OCR服务：配置为空');
      }
    } catch (e) {
      print('ScreenShotServe: 初始化OCR服务失败: $e');
      rethrow;
    }
  }
  
  /// 处理截图并转换为markdown文档
  Future<Map<String, dynamic>> processScreenshot(String imagePath) async {
    if (!_isInitialized) {
      return {
        'success': false,
        'message': '截图服务未初始化，请先调用initialize方法',
      };
    }
    
    try {
      // 执行OCR识别
      final ocrResult = await _ocr.processToText(imagePath);
      
      if (!ocrResult['success']) {
        return ocrResult;
      }
      
      final extractedText = ocrResult['text'];
      
      // 使用LLM生成标题和摘要
      final titleAndSummary = await _generateTitleAndSummary(extractedText);
      
      // 创建Markdown文档
      final mdContent = await _createMarkdownDocument(
        title: titleAndSummary['title']!,
        summary: titleAndSummary['summary']!,
        content: extractedText,
        imagePath: imagePath,
      );
      
      // 保存Markdown文档
      final docFile = await _saveMarkdownDocument(mdContent, titleAndSummary['title']!);
      
      return {
        'success': true,
        'message': 'OCR识别并保存为Markdown文档成功',
        'doc_file': docFile.path,
        'title': titleAndSummary['title'],
        'summary': titleAndSummary['summary'],
      };
    } catch (e) {
      print('处理截图失败: $e');
      return {
        'success': false,
        'message': '处理截图失败: $e',
      };
    }
  }
  
  /// 使用LLM生成标题和摘要
  Future<Map<String, String>> _generateTitleAndSummary(String content) async {
    try {
      final result = await _llm.predict(
        inputText: content,
        sysPrompt: '你是一位优秀的文档整理助手。请根据以下文本内容，生成一个简洁的标题和一个简短的摘要。请以JSON格式返回，包含title和summary两个字段。',
      );
      
      // 尝试解析LLM返回的内容为JSON
      try {
        final jsonStr = result['content'];
        final jsonData = jsonDecode(jsonStr);
        
        return {
          'title': jsonData['title'] ?? '未命名文档',
          'summary': jsonData['summary'] ?? '无摘要',
        };
      } catch (e) {
        // 如果JSON解析失败，尝试生成默认标题
        print('解析LLM返回的JSON失败: $e');
        return {
          'title': '截图文档_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}',
          'summary': content.length > 100 ? content.substring(0, 100) + '...' : content,
        };
      }
    } catch (e) {
      print('生成标题和摘要失败: $e');
      return {
        'title': '截图文档_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}',
        'summary': content.length > 100 ? content.substring(0, 100) + '...' : content,
      };
    }
  }
  
  /// 使用LLM生成文件名
  Future<String> _generateFileName(String title, String content) async {
    try {
      print('开始使用LLM生成文件名...');
      // 扩展输入内容到2000字符
      final input_text = '标题: $title\n内容摘要: ${content.length > 2000 ? content.substring(0, 2000) + '...' : content}';
      final result = await _llm.predict(
        inputText: input_text,
        sysPrompt: '你是一位文件命名助手。请根据提供的文档标题和内容摘要，生成一个简洁、清晰的中文文件名（不含扩展名）。文件名应该能够反映文档的内容，便于归档和检索。请只返回文件名本身，不要添加其他文字或说明。可以使用中文、英文、数字和下划线，避免使用以下特殊字符：/ \\ : * ? " < > |',
      );
      print('LLM返回结果: $result');  
      final fileName = result['content'].toString().trim();
      print('LLM生成的文件名: $fileName');
      
      // 检查生成的文件名是否有效，如果无效则回退到默认命名
      if (fileName.isEmpty || fileName.length > 100) {
        print('生成的文件名无效，使用默认文件名');
        return _sanitizeFileName(title);
      }
      
      // 清理文件名，只移除文件系统不支持的特殊字符，保留中文
      final cleanedFileName = _sanitizeFileName(fileName);
      return cleanedFileName;
    } catch (e) {
      print('生成文件名失败: $e');
      // 回退到使用标题作为文件名
      return _sanitizeFileName(title);
    }
  }
  
  /// 清理文件名，移除文件系统不支持的字符，但保留中文
  String _sanitizeFileName(String fileName) {
    // 只移除文件系统不支持的特殊字符，保留中文、英文、数字、空格、下划线、连字符
    // Windows文件系统不支持的字符: / \ : * ? " < > |
    // 同时处理中文标点符号：：（中文冒号）、《》（书名号）等
    return fileName
        .replaceAll(RegExp(r'[/\\:*?"<>|]'), '_')  // 英文特殊字符
        .replaceAll('：', '_')  // 中文冒号
        .replaceAll('《', '_')  // 中文左书名号
        .replaceAll('》', '_')  // 中文右书名号
        .replaceAll('？', '_')  // 中文问号
        .replaceAll('"', '_')   // 中文左双引号
        .replaceAll('"', '_');  // 中文右双引号
  }
  
  /// 创建Markdown文档内容
  Future<String> _createMarkdownDocument({
    required String title,
    required String summary,
    required String content,
    required String imagePath,
  }) async {
    final dateTime = DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now());
    final imageFileName = path.basename(imagePath);
    
    // 创建文档内容
    return '''
# $title

> $summary

## 元数据
- 创建时间: $dateTime
- 来源: OCR识别
- 原始图片: $imageFileName

## 内容

$content

''';
  }
  
  /// 保存Markdown文档到文件
  Future<File> _saveMarkdownDocument(String content, String title) async {
    try {
      // 使用大模型生成文件名
      final baseFileName = await _generateFileName(title, content);
      
      // 添加_OCR后缀
      String fileName = '${baseFileName}_OCR.md';
      print('初始文件名: $fileName');
      
      // 获取文档目录
      final docDir = Directory(path.join(_fileServe.appDataDir, 'doc'));
      if (!await docDir.exists()) {
        await docDir.create(recursive: true);
      }
      
      // 检查文件是否存在，如果存在则添加数字
      File file = File(path.join(docDir.path, fileName));
      int counter = 1;
      while (await file.exists()) {
        fileName = '${baseFileName}_${counter}_OCR.md';
        file = File(path.join(docDir.path, fileName));
        counter++;
      }
      
      // 保存文件
      await file.writeAsString(content);
      print('文档已保存到: ${file.path}');
      return file;
    } catch (e) {
      print('保存Markdown文档失败: $e');
      // 发生错误时使用默认方式保存
      final sanitizedTitle = _sanitizeFileName(title);
      String fileName = '${sanitizedTitle}_OCR.md';
      
      final docDir = Directory(path.join(_fileServe.appDataDir, 'doc'));
      if (!await docDir.exists()) {
        await docDir.create(recursive: true);
      }
      
      // 检查文件是否存在，如果存在则添加数字
      File file = File(path.join(docDir.path, fileName));
      int counter = 1;
      while (await file.exists()) {
        fileName = '${sanitizedTitle}_${counter}_OCR.md';
        file = File(path.join(docDir.path, fileName));
        counter++;
      }
      
      await file.writeAsString(content);
      return file;
    }
  }
} 